package com.wdcg.fragment;

import java.util.HashMap;
import java.util.List;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.wdcg.R;
import com.wdcg.model.access.DwarfAccess;
import com.wdcg.model.dao.Dwarf;
import com.wdcg.model.dao.DwarfDescription;
import com.wdcg.utils.GameLogic;
import com.wdcg.utils.LocationProcessor;
import com.wdcg.utils.LocationProcessor.LocationProcessorUpdate;
import com.wdcg.utils.NotificationUtils;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class MapFragment extends Fragment implements LocationProcessorUpdate, OnMarkerClickListener{

	private SupportMapFragment fragment;
    private GoogleMap map;
    
	private Location location;
	private LocationProcessor locationProcessor;
	
	private Marker userMarker;
	private Circle userCirlce;
	
	private HashMap<Integer, Marker> markers;
	private HashMap<String, Integer> markersIds;
	
	private final int circleRadius = 750;
	
	private List<DwarfDescription> visibleDwarfes;

	private boolean first;
	
	@Override
    public void onCreate(Bundle savedInstanceState) {                
            super.onCreate(savedInstanceState);
               	
    }

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		
		View v = inflater.inflate(R.layout.fragment_map, container, false);

		markers = new HashMap<Integer, Marker>();
		markersIds = new HashMap<String, Integer>();
        
        first = true;
		
		return v;
	}



	private void initilizeMap() {
		
        if (map == null) {
        	map=fragment.getMap();
        }
        
        List<DwarfDescription> temp = DwarfAccess.getDwarvesDescriptions();
        
        visibleDwarfes = DwarfAccess.getVisibleDwarvesDescriptions(true);
    	
    	for(DwarfDescription dwarfDesc: visibleDwarfes){
    		Marker myMarker=map.addMarker(new MarkerOptions().
    				position(new LatLng(dwarfDesc.getDwarf().getLatitude(), dwarfDesc.getDwarf().getLongitude())).
    		icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_dwarf_inactive))
    		);
    		
    		markers.put(dwarfDesc.getDwarf().getId(), myMarker);
    		markersIds.put(myMarker.getId(), dwarfDesc.getDwarf().getId());
    	}
    	
    	map.setOnMarkerClickListener(this);
                
       
    }  
   

	public void onLocationChanged(Location location) {
		
		this.location=location;
		
		if(map!=null){
			if (userMarker!=null) 
				userMarker.remove();

			if (userCirlce!=null) 
				userCirlce.remove();

			
			if(first){

				map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15));
				map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

				first = false;
			}

			userMarker = map.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude()))
					.title(getResources().getString(R.string.user_marker)));
			
			userCirlce = map.addCircle(new CircleOptions().center(new LatLng(location.getLatitude(), location.getLongitude())).
				radius(circleRadius).
				fillColor(R.color.map_cirlce_background).
				strokeWidth(1)
				
				
			);
			
			for(DwarfDescription dwarfDesc: visibleDwarfes){
				if(isDwarfNear(location, dwarfDesc.getDwarf().getLatitude(), dwarfDesc.getDwarf().getLongitude())){
					Marker markerToChange = markers.remove(dwarfDesc.getDwarf().getId());
					markerToChange.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.marker_dwarf));
					markers.put(dwarfDesc.getDwarf().getId(), markerToChange);
				}
			}
		}
	}

	@Override
	public void onPause() {
		
		locationProcessor.disconnectLocationClient();
		locationProcessor=null;
		
		if (map!=null) {
			map.clear();
		}
		map = null;
		super.onPause();
	}

	@Override
	public void onResume() {
		
		initilizeMap();
		
		if (locationProcessor==null)
			locationProcessor = new LocationProcessor(getActivity(), this);
    	
		
		locationProcessor.connectLocationClient();
		
		super.onResume();
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		FragmentManager fm = getChildFragmentManager();
        fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
        if (fragment == null) {
                fragment = SupportMapFragment.newInstance();
                fm.beginTransaction().replace(R.id.map, fragment).commit();
        }
		super.onActivityCreated(savedInstanceState);
	}
	
	private boolean isDwarfNear(Location userLocation, double dwarfLat, double dwarfLong){
		
		Location dwarfLocation = new Location("Dwarf");
		dwarfLocation.setLatitude(dwarfLat);
		dwarfLocation.setLongitude(dwarfLong);
		
		if(userLocation.distanceTo(dwarfLocation)<=circleRadius)
			return true;
		else
			return false;
		
	}

	public boolean onMarkerClick(final Marker marker) {
		if(marker.equals(userMarker))
			return false;
		
		Log.d("DwarfClick", "ClickMarker");
		
		if(isDwarfNear(location, marker.getPosition().latitude, marker.getPosition().longitude)){
			
			AlertDialog.Builder playDialog = new AlertDialog.Builder(getActivity());
			
			playDialog.setTitle(getResources().getString(R.string.find_dwarf_text));
			playDialog.setMessage(getResources().getString(R.string.wanna_play_a_game_text));
			playDialog.setPositiveButton(getResources().getString(R.string.play_game_dialog_yes), new OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					
					int dwarfId = markersIds.get(marker.getId());
					
					Dwarf dwarf = null;
					
					for(DwarfDescription dwarfDesc: visibleDwarfes){
						if(dwarfDesc.getDwarf().getId()==dwarfId)
							dwarf=dwarfDesc.getDwarf();
					}
					
					GameLogic.setDwarfWaitingForPlay(dwarf);
					GameLogic.playMiniGame(getActivity(), dwarfId);
					
				}
			});
			
			playDialog.setNegativeButton(getResources().getString(R.string.play_game_dialog_no), new OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					
				}
			});
			
			AlertDialog dialog = playDialog.create();
			dialog.show();
			
			
		}
		else{
			Toast.makeText(getActivity(), getResources().getString(R.string.click_outside_circle), Toast.LENGTH_SHORT).show();
		}
		
		return true;
		
	}
    
}
